package com.weixin.api.content.aop;

import com.google.gson.Gson;
import com.weixin.util.CommonUtil;
import org.apache.logging.log4j.core.config.Order;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * AOP日志管理
 *
 * @author lc
 * @email 389125111@qq.com
 * @create 2018-03-14 14:42
 */
@Aspect
@Component
@Order(1)
public class AdviceAop {
    private final static Logger logger = LoggerFactory.getLogger(AdviceAop.class);


    /**
     * @Pointcut 定义一个方法为切点里面的内容为一个表达式, 下面详细介绍
     * @Before 在切点前执行方法, 内容为指定的切点
     * @After 在切点后, return前执行,
     * @AfterReturning 在切入点, return后执行, 如果想对某些方法的返回参数进行处理, 可以在这操作
     * @Around 环绕切点, 在进入切点前, 跟切点后执行
     * @AfterThrowing 在切点后抛出异常进行处理
     * @order(i) 标记切点的优先级, i越小, 优先级越高
     */
    @Pointcut("execution(public * com.weixin.api.rest.*.*(..))")
    public void webLog() {
    }

    @Before("webLog()")
    public void beforeAdvice(JoinPoint joinPoint) {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();

        logger.debug("请求地址 : " + request.getRequestURI().toString());
        logger.debug("请求方式 ：" + request.getMethod());
        logger.debug("IP地址 ：" + request.getRemoteAddr());
        logger.debug("请求方法 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + "()");

        Object[] params = joinPoint.getArgs();
        if (null != params) {
            StringBuffer inputParam = new StringBuffer();
            Gson gson = new Gson();
            for (int i = 0; i < params.length; i++) {
                Object param = params[i];
                if (null != param) {
                    if (!CommonUtil.isBaseType(param)) {
                        if (param instanceof HttpServletRequest) {
                            continue;
                        } else if (param instanceof HttpServletResponse) {
                            continue;
                        } else if (param instanceof Model) {
                            continue;
                        } else {
                            inputParam.append(String.format(" [%s]", i));
                            inputParam.append(String.format("[%s]", param.getClass().getName()));
                            if (i == params.length - 1) {
                                inputParam.append("-->").append(gson.toJson(param).toString()).append(" ");
                            } else {
                                inputParam.append("-->").append(gson.toJson(param).toString()).append(" , ");
                            }
                        }
                    } else {
                        inputParam.append(String.format("[%s]", i));
                        if (i == params.length - 1) {
                            inputParam.append("-->").append(param).append(" ");
                        } else {
                            inputParam.append("-->").append(param).append(" , ");
                        }
                    }
                } else {
                    logger.debug("请求参数 : 无 .");
                }
            }
            logger.debug("请求参数 : 【" + inputParam.toString() + "】");
        } else {
            logger.debug("请求参数 : 无 .");
        }
    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        logger.info("response : " + ret);
    }


}
